﻿<!DOCTYPE html>
<html class="theme theme-white">
<head>
<meta charset="utf-8">
<title>MyBatis面试题</title>
<link href="https://www.zybuluo.com/static/assets/template-theme-white.css" rel="stylesheet" media="screen">
<style type="text/css">

#wmd-preview h1  {
    color: #0077bb; /* 将标题改为蓝色 */
}</style>
</head>
<body class="theme theme-white">
<div id="wmd-preview" class="wmd-preview wmd-preview-full-reader"><div class="md-section-divider"></div><div class="md-section-divider"></div><h1 data-anchor-id="a1nl" id="mybatis面试题">MyBatis面试题</h1><p data-anchor-id="i5sz"><code>Java面试题</code></p><hr><div class="md-section-divider"></div><h3 data-anchor-id="nqm7" id="jdbc编程有哪些不足之处mybatis是如何解决这些问题的">JDBC编程有哪些不足之处，MyBatis是如何解决这些问题的？</h3><p data-anchor-id="9ht1">① 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能，如果使用数据库链接池可解决此问题。 <br>
解决：在SqlMapConfig.xml中配置数据链接池，使用连接池管理数据库链接。</p><p data-anchor-id="wurl">② Sql语句写在代码中造成代码不易维护，实际应用sql变化的可能较大，sql变动需要改变java代码。 <br>
解决：将Sql语句配置在XXXXmapper.xml文件中与java代码分离。</p><p data-anchor-id="3bsq">③ 向sql语句传参数麻烦，因为sql语句的where条件不一定，可能多也可能少，占位符需要和参数一一对应。 <br>
解决： Mybatis自动将java对象映射至sql语句。</p><p data-anchor-id="v1h7">④ 对结果集解析麻烦，sql变化导致解析代码变化，且解析前需要遍历，如果能将数据库记录封装成pojo对象解析比较方便。 <br>
解决：Mybatis自动将sql执行结果映射至java对象。</p><div class="md-section-divider"></div><h3 data-anchor-id="6sl5" id="mybatis编程步骤是什么样的">MyBatis编程步骤是什么样的？</h3><p data-anchor-id="vztx">① 创建SqlSessionFactory  <br>
② 通过SqlSessionFactory创建SqlSession  <br>
③ 通过sqlsession执行数据库操作  <br>
④ 调用session.commit()提交事务  <br>
⑤ 调用session.close()关闭会话</p><div class="md-section-divider"></div><h3 data-anchor-id="4h6m" id="mybatis与hibernate有哪些不同">MyBatis与Hibernate有哪些不同？</h3><p data-anchor-id="torm">Mybatis和hibernate不同，它不完全是一个ORM框架，因为MyBatis需要程序员自己编写Sql语句，不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句，并将java对象和sql语句映射生成最终执行的sql，最后将sql执行的结果再映射生成java对象。 </p><p data-anchor-id="xysl">Mybatis学习门槛低，简单易学，程序员直接编写原生态sql，可严格控制sql执行性能，灵活度高，非常适合对关系数据模型要求不高的软件开发，例如互联网软件、企业运营类软件等，因为这类软件需求变化频繁，一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性，如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件，工作量大。 </p><p data-anchor-id="bgmv">Hibernate对象/关系映射能力强，数据库无关性好，对于关系模型要求高的软件（例如需求固定的定制化软件）如果用hibernate开发可以节省很多代码，提高效率。但是Hibernate的缺点是学习门槛高，要精通门槛更高，而且怎么设计O/R映射，在性能和对象模型之间如何权衡，以及怎样用好Hibernate需要具有很强的经验和能力才行。  <br>
总之，按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构，所以框架只有适合才是最好。</p><div class="md-section-divider"></div><h3 data-anchor-id="u8q4" id="使用mybatis的mapper接口调用时有哪些要求">使用MyBatis的mapper接口调用时有哪些要求？</h3><p data-anchor-id="dspk">①  Mapper接口方法名和mapper.xml中定义的每个sql的id相同  <br>
②  Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同  <br>
③  Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同  <br>
④  Mapper.xml文件中的namespace即是mapper接口的类路径。 <br>
5.SqlMapConfig.xml中配置有哪些内容？ <br>
SqlMapConfig.xml中配置的内容和顺序如下：  <br>
properties（属性） <br>
settings（配置） <br>
typeAliases（类型别名） <br>
typeHandlers（类型处理器） <br>
objectFactory（对象工厂） <br>
plugins（插件） <br>
environments（环境集合属性对象） <br>
environment（环境子属性对象） <br>
transactionManager（事务管理） <br>
dataSource（数据源） <br>
mappers（映射器）</p><div class="md-section-divider"></div><h3 data-anchor-id="7c4p" id="简单的说一下mybatis的一级缓存和二级缓存">简单的说一下MyBatis的一级缓存和二级缓存？</h3><p data-anchor-id="cihj">Mybatis首先去缓存中查询结果集，如果没有则查询数据库，如果有则从缓存取出返回结果集就不走数据库。Mybatis内部存储缓存使用一个HashMap，key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象</p><p data-anchor-id="jnv6">Mybatis的二级缓存即查询缓存，它的作用域是一个mapper的namespace，即在同一个namespace中查询sql可以从缓存中获取数据。二级缓存是可以跨SqlSession的。</p><div class="md-section-divider"></div><h3 data-anchor-id="rup3" id="mapper编写有哪几种方式">Mapper编写有哪几种方式？</h3><p data-anchor-id="6sql">①接口实现类继承SqlSessionDaoSupport <br>
使用此种方法需要编写mapper接口，mapper接口实现类、mapper.xml文件</p><p data-anchor-id="n6ht">1、在sqlMapConfig.xml中配置mapper.xml的位置</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="mx0f"><ol class="linenums"><li class="L0"><code><span class="tag">&lt;mappers&gt;</span></code></li><li class="L1"><code><span class="pln">    </span><span class="tag">&lt;mapper</span><span class="pln"> </span><span class="atn">resource</span><span class="pun">=</span><span class="atv">"mapper.xml文件的地址"</span><span class="pln"> </span><span class="tag">/&gt;</span></code></li><li class="L2"><code><span class="pln">    </span><span class="tag">&lt;mapper</span><span class="pln"> </span><span class="atn">resource</span><span class="pun">=</span><span class="atv">"mapper.xml文件的地址"</span><span class="pln"> </span><span class="tag">/&gt;</span></code></li><li class="L3"><code><span class="tag">&lt;/mappers&gt;</span></code></li></ol></pre><p data-anchor-id="5dyy">2、定义mapper接口</p><p data-anchor-id="n8g2">3、实现类集成SqlSessionDaoSupport</p><p data-anchor-id="xnq8">mapper方法中可以this.getSqlSession()进行数据增删改查。</p><p data-anchor-id="tfsw">4、spring 配置</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="2phi"><ol class="linenums"><li class="L0"><code><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">" "</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"mapper接口的实现"</span><span class="tag">&gt;</span></code></li><li class="L1"><code><span class="pln">    </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="atn">ref</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="tag">&gt;&lt;/property&gt;</span></code></li><li class="L2"><code><span class="tag">&lt;/bean&gt;</span></code></li></ol></pre><p data-anchor-id="chwe">②使用org.mybatis.spring.mapper.MapperFactoryBean</p><p data-anchor-id="1h7j">1、在sqlMapConfig.xml中配置mapper.xml的位置</p><p data-anchor-id="bvcx">如果mapper.xml和mappre接口的名称相同且在同一个目录，这里可以不用配置</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="80pk"><ol class="linenums"><li class="L0"><code><span class="tag">&lt;mappers&gt;</span></code></li><li class="L1"><code><span class="pln">    </span><span class="tag">&lt;mapper</span><span class="pln"> </span><span class="atn">resource</span><span class="pun">=</span><span class="atv">"mapper.xml文件的地址"</span><span class="pln"> </span><span class="tag">/&gt;</span></code></li><li class="L2"><code><span class="pln">    </span><span class="tag">&lt;mapper</span><span class="pln"> </span><span class="atn">resource</span><span class="pun">=</span><span class="atv">"mapper.xml文件的地址"</span><span class="pln"> </span><span class="tag">/&gt;</span></code></li><li class="L3"><code><span class="tag">&lt;/mappers&gt;</span></code></li></ol></pre><p data-anchor-id="zf61">2、定义mapper接口</p><p data-anchor-id="mf53">注意</p><p data-anchor-id="5wse">1、mapper.xml中的namespace为mapper接口的地址</p><p data-anchor-id="qcd2">2、mapper接口中的方法名和mapper.xml中的定义的statement的id保持一致</p><p data-anchor-id="y7k2">3、 Spring中定义</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="i321"><ol class="linenums"><li class="L0"><code><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">""</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"org.mybatis.spring.mapper.MapperFactoryBean"</span><span class="tag">&gt;</span></code></li><li class="L1"><code><span class="pln">    </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"mapperInterface"</span><span class="pln">   </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"mapper接口地址"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln"> </span></code></li><li class="L2"><code><span class="pln">    </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="atn">ref</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln"> </span></code></li><li class="L3"><code><span class="tag">&lt;/bean&gt;</span></code></li></ol></pre><p data-anchor-id="ij6g">③使用mapper扫描器</p><p data-anchor-id="rbs5">1、mapper.xml文件编写</p><blockquote data-anchor-id="bx6g" class="white-blockquote">
  <p>注意： <br>
  mapper.xml中的namespace为mapper接口的地址 <br>
  mapper接口中的方法名和mapper.xml中的定义的statement的id保持一致 <br>
  如果将mapper.xml和mapper接口的名称保持一致则不用在sqlMapConfig.xml中进行配置 </p>
</blockquote><p data-anchor-id="y7b2">2、定义mapper接口</p><blockquote data-anchor-id="ni3z" class="white-blockquote">
  <p>注意mapper.xml的文件名和mapper的接口名称保持一致，且放在同一个目录</p>
</blockquote><p data-anchor-id="45dj">3、配置mapper扫描器</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="b51u"><ol class="linenums"><li class="L0"><code><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"org.mybatis.spring.mapper.MapperScannerConfigurer"</span><span class="tag">&gt;</span></code></li><li class="L1"><code><span class="pln">    </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"basePackage"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"mapper接口包地址"</span><span class="tag">&gt;&lt;/property&gt;</span></code></li><li class="L2"><code><span class="pln">    </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"sqlSessionFactoryBeanName"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="tag">/&gt;</span><span class="pln"> </span></code></li><li class="L3"><code><span class="tag">&lt;/bean&gt;</span></code></li></ol></pre><p data-anchor-id="l06l">4、使用扫描器后从spring容器中获取mapper的实现对象扫描器将接口通过代理方法生成实现对象，要spring容器中自动注册，名称为mapper 接口的名称。</p><div class="md-section-divider"></div><h3 data-anchor-id="gklo" id="结束">结束</h3><p data-anchor-id="ouss">参考： <br>
<a href="http://www.cnblogs.com/wang-meng/p/5701990.html" target="_blank">[Java面试七]Mybatis总结以及在面试中的一些问题.</a></p></div>
</body>
</html>